package net.teamclerks.kain.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;


/*
 * URLUtils.java
 *
 * Copyright (C) 2007 Mike 'kain' Smith
 * 
 * This is part of HelperBot
 * 
 * HelperBot is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * HelperBot is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

public final class URLUtils {

  private URLUtils(){}

  private static Pattern pattern = Pattern.compile(URLUtils.URLRegex);
  
  /**
   * Helper
   * @param url
   * @return
   */
  public static boolean isValidUrl(String url)
  {
    return pattern.matcher(url).matches();
  }
  
  public static boolean isHtmlKeyword(String key)
  {
    if(key.equalsIgnoreCase("http")) return true;
    if(key.equalsIgnoreCase("www")) return true;
    if(key.equalsIgnoreCase("com")) return true;
    if(key.equalsIgnoreCase("html")) return true;
    if(key.equalsIgnoreCase("shtml")) return true;
    if(key.equalsIgnoreCase("htm")) return true;
    if(key.equalsIgnoreCase("php")) return true;
    if(key.equalsIgnoreCase("asp")) return true;
    if(key.equalsIgnoreCase("ftp")) return true;
    if(key.equalsIgnoreCase("ftp")) return true;
    if(key.equalsIgnoreCase("txt")) return true;
    if(key.equalsIgnoreCase("css")) return true;
    if(key.equalsIgnoreCase("png")) return true;
    if(key.equalsIgnoreCase("gif")) return true;
    if(key.equalsIgnoreCase("tif")) return true;
    if(key.equalsIgnoreCase("tiff")) return true;
    if(key.equalsIgnoreCase("jp2")) return true;
    if(key.equalsIgnoreCase("jpg")) return true;
    if(key.equalsIgnoreCase("jpe")) return true;
    if(key.equalsIgnoreCase("jpeg")) return true;
    if(key.equalsIgnoreCase("pjpeg")) return true;
    if(key.equalsIgnoreCase("pjp")) return true;
    if(key.equalsIgnoreCase("bmp")) return true;
    if(key.equalsIgnoreCase("djv")) return true;
    if(key.equalsIgnoreCase("djvu")) return true;
    if(key.equalsIgnoreCase("ico")) return true;
    if(key.equalsIgnoreCase("ief")) return true;
    if(key.equalsIgnoreCase("ifs")) return true;
    if(key.equalsIgnoreCase("mac")) return true;
    if(key.equalsIgnoreCase("pbm")) return true;
    if(key.equalsIgnoreCase("pic")) return true;
    if(key.equalsIgnoreCase("pict")) return true;
    if(key.equalsIgnoreCase("pct")) return true;
    if(key.equalsIgnoreCase("pgm")) return true;
    if(key.equalsIgnoreCase("pnm")) return true;
    if(key.equalsIgnoreCase("pnt")) return true;
    if(key.equalsIgnoreCase("pntg")) return true;
    if(key.equalsIgnoreCase("ppm")) return true;
    if(key.equalsIgnoreCase("qti")) return true;
    if(key.equalsIgnoreCase("qtif")) return true;
    if(key.equalsIgnoreCase("ras")) return true;
    if(key.equalsIgnoreCase("rgb")) return true;
    if(key.equalsIgnoreCase("svg")) return true;
    if(key.equalsIgnoreCase("wbmp")) return true;
    if(key.equalsIgnoreCase("xbm")) return true;
    if(key.equalsIgnoreCase("xpm")) return true;
    if(key.equalsIgnoreCase("cgm")) return true;
    if(key.equalsIgnoreCase("xwd")) return true;
    if(key.equalsIgnoreCase("fif")) return true;
    if(key.equalsIgnoreCase("jfif")) return true;
    if(key.equalsIgnoreCase("dwg")) return true;
    if(key.equalsIgnoreCase("svf")) return true;
    if(key.equalsIgnoreCase("wi")) return true;
    if(key.equalsIgnoreCase("pcd")) return true;
    if(key.equalsIgnoreCase("wav")) return true;
    if(key.equalsIgnoreCase("mp3")) return true;
    if(key.equalsIgnoreCase("mpeg")) return true;
    if(key.equalsIgnoreCase("mpg")) return true;
    if(key.equalsIgnoreCase("mpe")) return true;
    if(key.equalsIgnoreCase("avi")) return true;
    if(key.equalsIgnoreCase("mov")) return true;
    if(key.equalsIgnoreCase("movie")) return true;
    if(key.equalsIgnoreCase("ps")) return true;
    if(key.equalsIgnoreCase("pdf")) return true;
    if(key.equalsIgnoreCase("latex")) return true;
    if(key.equalsIgnoreCase("dvi")) return true;
    if(key.equalsIgnoreCase("doc")) return true;
    if(key.equalsIgnoreCase("gtar")) return true;
    if(key.equalsIgnoreCase("tar")) return true;
    if(key.equalsIgnoreCase("ustar")) return true;
    if(key.equalsIgnoreCase("bcpio")) return true;
    if(key.equalsIgnoreCase("cpio")) return true;
    if(key.equalsIgnoreCase("shar")) return true;
    if(key.equalsIgnoreCase("zip")) return true;
    if(key.equalsIgnoreCase("hqx")) return true;
    if(key.equalsIgnoreCase("sit")) return true;
    if(key.equalsIgnoreCase("sea")) return true;
    if(key.equalsIgnoreCase("bin")) return true;
    if(key.equalsIgnoreCase("exe")) return true;
    if(key.equalsIgnoreCase("js")) return true;
    if(key.equalsIgnoreCase("csh")) return true;
    if(key.equalsIgnoreCase("pl")) return true;
    if(key.equalsIgnoreCase("tcl")) return true;
    if(key.equalsIgnoreCase("asp")) return true;
    if(key.equalsIgnoreCase("ppt")) return true;
    return false;
  }
  
  /**
   * Returns a list of strings of the URL 'chunked' into small
   * useful strings.
   * @author kain
   * @param url
   * @return List<String>
   */
  public static List<String> chunk(String url)
  {
    ArrayList<String> output = new ArrayList<String>();
    for(String s: url.split("[^A-Za-z0-9]"))
    {
      if(!s.equalsIgnoreCase(""))
      {
        output.add(s);
      }
    }
    return output;
  }
  
  /**
   * This is the regular expression that describes URL strings.<br/>
   * <br/>
   * Comparison source:<br/>
   * RFC 1738: Uniform Resource Locators (URL)<br/>
   * http://www.ietf.org/rfc/rfc1738.txt
   * 
   * @author kain
   */
  public final static String URLRegex = 
    "(?:http://(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\." +
    ")*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)" + 
    "){3}))(?::(?:\\d+))?)(?:/(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F" +
    "\\d]{2}))|[;:@&=])*)(?:/(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{" + 
    "2}))|[;:@&=])*))*)(?:\\?(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{" +
    "2}))|[;:@&=])*))?)?)|(?:ftp://(?:(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?" + 
    ":%[a-fA-F\\d]{2}))|[;?&=])*)(?::(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-" +
    "fA-F\\d]{2}))|[;?&=])*))?@)?(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-" +
    ")*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?" +
    ":\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))?))(?:/(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!" +
    "*'(),]|(?:%[a-fA-F\\d]{2}))|[?:@&=])*)(?:/(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'()" +
    ",]|(?:%[a-fA-F\\d]{2}))|[?:@&=])*))*)(?:;type=[AIDaid])?)?)|(?:news:(?:" +
    "(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[;/?:&=])+@(?:(?:(" +
    "?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[" +
    "a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3})))|(?:[a-zA-Z](" +
    "?:[a-zA-Z\\d]|[_.+-])*)|\\-))|(?:nntp://(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[" +
    "a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d" +
    "])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))?)/(?:[a-zA-Z](?:[a-zA-Z" +
    "\\d]|[_.+-])*)(?:/(?:\\d+))?)|(?:telnet://(?:(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+" +
    "!*'(),]|(?:%[a-fA-F\\d]{2}))|[;?&=])*)(?::(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'()" +
    ",]|(?:%[a-fA-F\\d]{2}))|[;?&=])*))?@)?(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a" +
    "-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d]" +
    ")?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))?))/?)|(?:gopher://(?:(?:" +
    "(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:" +
    "(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+" +
    "))?)(?:/(?:[a-zA-Z\\d$\\-_.+!*'(),;/?:@&=]|(?:%[a-fA-F\\d]{2}))(?:(?:(?:[" +
    "a-zA-Z\\d$\\-_.+!*'(),;/?:@&=]|(?:%[a-fA-F\\d]{2}))*)(?:%09(?:(?:(?:[a-zA" +
    "-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[;:@&=])*)(?:%09(?:(?:[a-zA-Z\\d$" +
    "\\-_.+!*'(),;/?:@&=]|(?:%[a-fA-F\\d]{2}))*))?)?)?)?)|(?:wais://(?:(?:(?:" +
    "(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:" +
    "[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))?" +
    ")/(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))*)(?:(?:/(?:(?:[a-zA" +
    "-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))*)/(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(" +
    "?:%[a-fA-F\\d]{2}))*))|\\?(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]" +
    "{2}))|[;:@&=])*))?)|(?:mailto:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),;/?:@&=]|(?:%" +
    "[a-fA-F\\d]{2}))+))|(?:file://(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]" +
    "|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:" +
    "(?:\\d+)(?:\\.(?:\\d+)){3}))|localhost)?/(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'()" +
    ",]|(?:%[a-fA-F\\d]{2}))|[?:@&=])*)(?:/(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(" +
    "?:%[a-fA-F\\d]{2}))|[?:@&=])*))*))|(?:prospero://(?:(?:(?:(?:(?:[a-zA-Z" +
    "\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)" +
    "*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))?)/(?:(?:(?:(?" +
    ":[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[?:@&=])*)(?:/(?:(?:(?:[a-" +
    "zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[?:@&=])*))*)(?:(?:;(?:(?:(?:[" +
    "a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[?:@&])*)=(?:(?:(?:[a-zA-Z\\d" +
    "$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[?:@&])*)))*)|(?:ldap://(?:(?:(?:(?:" +
    "(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:" +
    "[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))?" +
    "))?/(?:(?:(?:(?:(?:(?:(?:[a-zA-Z\\d]|%(?:3\\d|[46][a-fA-F\\d]|[57][Aa\\d])" +
    ")|(?:%20))+|(?:OID|oid)\\.(?:(?:\\d+)(?:\\.(?:\\d+))*))(?:(?:%0[Aa])?(?:%2" +
    "0)*)=(?:(?:%0[Aa])?(?:%20)*))?(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F" +
    "\\d]{2}))*))(?:(?:(?:%0[Aa])?(?:%20)*)\\+(?:(?:%0[Aa])?(?:%20)*)(?:(?:(?" +
    ":(?:(?:[a-zA-Z\\d]|%(?:3\\d|[46][a-fA-F\\d]|[57][Aa\\d]))|(?:%20))+|(?:OID" +
    "|oid)\\.(?:(?:\\d+)(?:\\.(?:\\d+))*))(?:(?:%0[Aa])?(?:%20)*)=(?:(?:%0[Aa])" +
    "?(?:%20)*))?(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))*)))*)(?:(" +
    "?:(?:(?:%0[Aa])?(?:%20)*)(?:[;,])(?:(?:%0[Aa])?(?:%20)*))(?:(?:(?:(?:(" +
    "?:(?:[a-zA-Z\\d]|%(?:3\\d|[46][a-fA-F\\d]|[57][Aa\\d]))|(?:%20))+|(?:OID|o" +
    "id)\\.(?:(?:\\d+)(?:\\.(?:\\d+))*))(?:(?:%0[Aa])?(?:%20)*)=(?:(?:%0[Aa])?(" +
    "?:%20)*))?(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))*))(?:(?:(?:" +
    "%0[Aa])?(?:%20)*)\\+(?:(?:%0[Aa])?(?:%20)*)(?:(?:(?:(?:(?:[a-zA-Z\\d]|%(" +
    "?:3\\d|[46][a-fA-F\\d]|[57][Aa\\d]))|(?:%20))+|(?:OID|oid)\\.(?:(?:\\d+)(?:" +
    "\\.(?:\\d+))*))(?:(?:%0[Aa])?(?:%20)*)=(?:(?:%0[Aa])?(?:%20)*))?(?:(?:[a" +
    "-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))*)))*))*(?:(?:(?:%0[Aa])?(?:%2" +
    "0)*)(?:[;,])(?:(?:%0[Aa])?(?:%20)*))?)(?:\\?(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+" +
    "!*'(),]|(?:%[a-fA-F\\d]{2}))+)(?:,(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-f" +
    "A-F\\d]{2}))+))*)?)(?:\\?(?:base|one|sub)(?:\\?(?:((?:[a-zA-Z\\d$\\-_.+!*'(" +
    "),;/?:@&=]|(?:%[a-fA-F\\d]{2}))+)))?)?)?)|(?:(?:z39\\.50[rs])://(?:(?:(?" +
    ":(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?)\\.)*(?:[a-zA-Z](?:(?" +
    ":[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:\\d+)){3}))(?::(?:\\d+))" +
    "?)(?:/(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))+)(?:\\+(?:(?:" +
    "[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))+))*(?:\\?(?:(?:[a-zA-Z\\d$\\-_" +
    ".+!*'(),]|(?:%[a-fA-F\\d]{2}))+))?)?(?:;esn=(?:(?:[a-zA-Z\\d$\\-_.+!*'()," +
    "]|(?:%[a-fA-F\\d]{2}))+))?(?:;rs=(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA" +
    "-F\\d]{2}))+)(?:\\+(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))+))*)" +
    "?))|(?:cid:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[;?:@&=" +
    "])*))|(?:mid:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[;?:@" +
    "&=])*)(?:/(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[;?:@&=]" +
    ")*))?)|(?:vemmi://(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z" +
    "\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\" +
    ".(?:\\d+)){3}))(?::(?:\\d+))?)(?:/(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a" +
    "-fA-F\\d]{2}))|[/?:@&=])*)(?:(?:;(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a" +
    "-fA-F\\d]{2}))|[/?:@&])*)=(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d" +
    "]{2}))|[/?:@&])*))*))?)|(?:imap://(?:(?:(?:(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+" +
    "!*'(),]|(?:%[a-fA-F\\d]{2}))|[&=~])+)(?:(?:;[Aa][Uu][Tt][Hh]=(?:\\-|(?:(" +
    "?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[&=~])+))))?)|(?:(?:;[" +
    "Aa][Uu][Tt][Hh]=(?:\\-|(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2" +
    "}))|[&=~])+)))(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[" +
    "&=~])+))?))@)?(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])" +
    "?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:\\.(?:" +
    "\\d+)){3}))(?::(?:\\d+))?))/(?:(?:(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:" +
    "%[a-fA-F\\d]{2}))|[&=~:@/])+)?;[Tt][Yy][Pp][Ee]=(?:[Ll](?:[Ii][Ss][Tt]|" +
    "[Ss][Uu][Bb])))|(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))" +
    "|[&=~:@/])+)(?:\\?(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[" +
    "&=~:@/])+))?(?:(?:;[Uu][Ii][Dd][Vv][Aa][Ll][Ii][Dd][Ii][Tt][Yy]=(?:[1-" +
    "9]\\d*)))?)|(?:(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[&=~" +
    ":@/])+)(?:(?:;[Uu][Ii][Dd][Vv][Aa][Ll][Ii][Dd][Ii][Tt][Yy]=(?:[1-9]\\d*" +
    ")))?(?:/;[Uu][Ii][Dd]=(?:[1-9]\\d*))(?:(?:/;[Ss][Ee][Cc][Tt][Ii][Oo][Nn" +
    "]=(?:(?:(?:[a-zA-Z\\d$\\-_.+!*'(),]|(?:%[a-fA-F\\d]{2}))|[&=~:@/])+)))?))" +
    ")?)|(?:nfs:(?:(?://(?:(?:(?:(?:(?:[a-zA-Z\\d](?:(?:[a-zA-Z\\d]|-)*[a-zA-" +
    "Z\\d])?)\\.)*(?:[a-zA-Z](?:(?:[a-zA-Z\\d]|-)*[a-zA-Z\\d])?))|(?:(?:\\d+)(?:" +
    "\\.(?:\\d+)){3}))(?::(?:\\d+))?)(?:(?:/(?:(?:(?:(?:(?:[a-zA-Z\\d\\$\\-_.!~*'" +
    "(),])|(?:%[a-fA-F\\d]{2})|[:@&=+])*)(?:/(?:(?:(?:[a-zA-Z\\d\\$\\-_.!~*'()," +
    "])|(?:%[a-fA-F\\d]{2})|[:@&=+])*))*)?)))?)|(?:/(?:(?:(?:(?:(?:[a-zA-Z\\d" +
    "\\$\\-_.!~*'(),])|(?:%[a-fA-F\\d]{2})|[:@&=+])*)(?:/(?:(?:(?:[a-zA-Z\\d\\$\\" +
    "-_.!~*'(),])|(?:%[a-fA-F\\d]{2})|[:@&=+])*))*)?))|(?:(?:(?:(?:(?:[a-zA-" +
    "Z\\d\\$\\-_.!~*'(),])|(?:%[a-fA-F\\d]{2})|[:@&=+])*)(?:/(?:(?:(?:[a-zA-Z\\d" +
    "\\$\\-_.!~*'(),])|(?:%[a-fA-F\\d]{2})|[:@&=+])*))*)?)))";  
}
